/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.javiermoreno.bankof.dominio.dao;

import com.javiermoreno.bankof.dominio.CuentaAhorro;
import com.javiermoreno.bankof.dominio.CuentaCorriente;
import com.javiermoreno.bankof.dominio.ProductoFinanciero;
import com.javiermoreno.framework.errores.SystemException;
import java.sql.*;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 *
 * @author Administrador
 */
public class ProductoFinancieroDAOImplJDBC 
implements ProductoFinancieroDAO {

    @Override
    public ProductoFinanciero findPorCodigo(String codigo) throws SystemException {
        Connection con = null;
        
        try {
            con = ConexionFactory.crear();
            String sql = "SELECT codigo, saldo, interesAnual, penalizada, tipo "
                       + "FROM productosfinancieros "
                       + "WHERE codigo = ?";
            PreparedStatement stmt = con.prepareStatement(sql);
            stmt.setString(1, codigo);            
            ResultSet rs = stmt.executeQuery();
            ProductoFinanciero pf = null;
            if (rs.next() == true) {
                pf = hidratarProductoFinanciero(rs);
            }
            return pf;
        } catch (SQLException exc) {
            exc.printStackTrace();
            SystemException sysExc = new SystemException(
                    "ProductoFinancieroDAOImplJDBC.findPorCodigo.error", exc);
            throw sysExc;
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException exc) {
                    exc.printStackTrace();
                }
            }
        }
    }

    @Override
    public Set<ProductoFinanciero> findPorCliente(String username) {
        Connection con = null;
        try {
            con = ConexionFactory.crear();
            String sql = "SELECT codigo, saldo, interesAnual, penalizada, tipo "
                       + "FROM productosfinancieros "
                       + "ORDER BY codigo ASC";
                     //+ "WHERE username = ?"
            PreparedStatement stmt = con.prepareStatement(sql);
            // stmt.setString(1, username);
            ResultSet rs = stmt.executeQuery();
            Set<ProductoFinanciero> productos = new LinkedHashSet<ProductoFinanciero>();
            while (rs.next() == true) {
                ProductoFinanciero pf = hidratarProductoFinanciero(rs);
                productos.add(pf);
            }
            return productos;
        } catch (SQLException exc) {
            exc.printStackTrace();
            SystemException sysExc = new SystemException(
                    "ProductoFinancieroDAOImplJDBC.findPorCliente.error", exc);
            throw sysExc;
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException exc) {
                    exc.printStackTrace();
                }
            }
        }
    }

  

    private ProductoFinanciero hidratarProductoFinanciero(ResultSet rs) throws SQLException {
        ProductoFinanciero pf = null;
        
        String tipo = rs.getString("tipo");
        if (tipo.equals("CC") == true)  {
            CuentaCorriente cc = new CuentaCorriente();
            pf = cc;
        } else if (tipo.equals("CA") == true) {
            CuentaAhorro ca = new CuentaAhorro();
            ca.setPenalizada(rs.getBoolean("penalizada"));
            pf = ca;
        }
        pf.setCodigo(rs.getString("codigo"));
        pf.setSaldo(rs.getDouble("saldo"));
        pf.setInteresAnual(rs.getDouble("interesAnual"));
        
        return pf;        
    }

     
    @Override
    public void actualizarProductoFinanciero(ProductoFinanciero producto) {
        Connection con = null;
        try {
            con = ConexionFactory.crear();
            if (this.updateProductoFinanciero(con, producto) == false) {
                this.insertProductoFinanciero(con, producto);
            }
        } catch (SQLException exc) {
            exc.printStackTrace();
            SystemException sysExc = new SystemException(
                    "ProductoFinancieroDAOImplJDBC.actualizarProductoFinanciero.error", exc);
            throw sysExc;
        } finally {
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException exc) {
                    exc.printStackTrace();
                }
            }
        }
    }

    private boolean updateProductoFinanciero(Connection con, ProductoFinanciero producto) 
    throws SQLException {
        String sql = "UPDATE productosfinancieros "
                   + "SET saldo=?, interesAnual=?, penalizada=? "
                   + "WHERE codigo = ?";
        PreparedStatement stmt = con.prepareStatement(sql);
        stmt.setDouble(1, producto.getSaldo());
        stmt.setDouble(2, producto.getInteresAnual());
        if (producto instanceof CuentaCorriente) {
            stmt.setNull(3, Types.BOOLEAN);
        } else if (producto instanceof CuentaAhorro) {
            CuentaAhorro ca = (CuentaAhorro) producto;
            stmt.setBoolean(3, ca.isPenalizada());
        }
        stmt.setString(4, producto.getCodigo());
        int filasAfectadas = stmt.executeUpdate();
        
        return filasAfectadas == 1;
    }
    
    private void insertProductoFinanciero(Connection con, ProductoFinanciero producto) 
    throws SQLException {
        String sql = "INSERT INTO productosfinancieros "
                   + "  (codigo, saldo, interesAnual, penalizada, tipo) "
                   + "VALUES (?, ?, ?, ?, ?)";
        PreparedStatement stmt = con.prepareStatement(sql);
        stmt.setString(1, producto.getCodigo());
        stmt.setDouble(2, producto.getSaldo());
        stmt.setDouble(3, producto.getInteresAnual());
        if (producto instanceof CuentaCorriente) {
            stmt.setNull(4, Types.BOOLEAN);
            stmt.setString(5, "CC");
        } else if (producto instanceof CuentaAhorro) {
            CuentaAhorro ca = (CuentaAhorro) producto;
            stmt.setBoolean(4, ca.isPenalizada());
            stmt.setString(5, "CA");
        }
        stmt.executeUpdate();
    }
    
    
}
